package com.lisa.auto.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.lisa.auto.entity.*;
import com.lisa.auto.entity.statistics.VehiclesStatisticsPo;
import com.lisa.auto.mapper.C3ReportCarInfoMapper;
import com.lisa.auto.scheduled.CarCondRecHandle;
import com.lisa.auto.service.*;
import com.lisa.auto.util.DateUtil;
import com.lisa.auto.util.DriveDirectionUtil;
import com.lisa.auto.util.basic.BaseException;
import com.lisa.json.JSONUtil;
import com.lisa.lang.TypeReference;
import com.lisa.redis.JedisClusterUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 上报车况信息 服务实现类
 * </p>
 *
 * @author suohao
 * @since 2019-12-25
 */
@Service
public class C3ReportCarInfoServiceImpl extends ServiceImpl<C3ReportCarInfoMapper, C3ReportCarInfo> implements C3ReportCarInfoService {

    private static final Logger LOGGER = LoggerFactory.getLogger(C3ReportCarInfoServiceImpl.class);

    @Autowired
    private IVehicleService vehicleService;
    @Autowired
    private C3ReportEventInfoService c3ReportEventInfoService;
    @Autowired
    private C3RiskFaultService riskFaultService;
    @Autowired
    private C3ReportCarFaultService c3ReportCarFaultService;
    @Autowired
    private C3ReportCarInfo1Service c3ReportCarInfo1Service;
    @Autowired
    private C3CarCondStatisticsService c3CarCondStatisticsService;


    /**
     * 车况上报
     * @param map
     */
    @Override
    public void reportCarInfo(Map<String, Object> map) {
        try {
            if (map.containsKey("list")){
                JedisClusterUtil.hSet(CarCondRecHandle.KEY_, DateUtil.format(DateUtil.DATE_TIME_1), map.get("list").toString());
                JedisClusterUtil.hSet(CarCondRecHandle.KEY_1, DateUtil.format(DateUtil.DATE_TIME_1), map.get("list").toString());
            }
        }catch (Exception e){
            LOGGER.info(e.getMessage(), e);
        }
        /*List<C3ReportCarInfo> conditionList = JSON.parseArray((String) map.get("list"), C3ReportCarInfo.class);
        // 车辆故障上报
        c3ReportCarFaultService.reportCarFault(map);
        if (CollectionUtils.isNotEmpty(conditionList)){
            conditionList.stream().forEach(c3ReportCarInfo->{
                if (c3ReportCarInfo.getLongitude().compareTo(BigDecimal.ZERO)==0 || c3ReportCarInfo.getLatitude().compareTo(BigDecimal.ZERO)==0){
                    return;
                }
                Map<String, Object> transAddress = DriveDirectionUtil.transAddress(c3ReportCarInfo);
                if (transAddress != null) {
                    if (transAddress.get("province").toString() != null && !"".equals(transAddress.get("province").toString())) {
                        c3ReportCarInfo.setProvince(transAddress.get("province").toString());
                    }
                    if (transAddress.get("city").toString() != null && !"".equals(transAddress.get("city").toString())) {
                        c3ReportCarInfo.setCity(transAddress.get("city").toString());
                    }
                    if (transAddress.get("district").toString() != null && !"".equals(transAddress.get("district").toString())) {
                        c3ReportCarInfo.setCounty(transAddress.get("district").toString());
                    }
                }
                C3ReportCar1Info c3ReportCar1Info = new C3ReportCar1Info();
                BeanUtils.copyProperties(c3ReportCarInfo, c3ReportCar1Info);
                baseMapper.insert(c3ReportCarInfo);
                c3ReportCarInfo1Service.add(c3ReportCar1Info);
            });
        }*/
    }

    @Override
    public List<C3ReportCarInfo> selCarCond(String vin) {
        Map<String, String> condition = new HashMap<>(3);
        if (StringUtils.isNotBlank(vin)){
            condition.put("vin", vin);
        }
        condition.put("startTime", DateUtil.getLastDate(DateUtil.DATE_1, -1) + " 00:00:00");
        condition.put("endTime", DateUtil.getLastDate(DateUtil.DATE_1, 0) + " 00:00:00");
        return baseMapper.selCarCond(condition);
    }

    @Override
    public List<C3ReportCarInfoVo> getCarCurrentInfoList(Map<String, Object> condition) {
        EntityWrapper<C3ReportCarInfo> ew = buildWrapper(condition);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar beforeTime = Calendar.getInstance();
        beforeTime.add(Calendar.MINUTE, -5);
        Date beforeD = beforeTime.getTime();
        condition.put("dateTime", sdf.format(beforeD));
        List<C3ReportCarInfoVo> infoList = baseMapper.getCarCurrentInfoList(ew, condition);
        infoList.removeAll(Collections.singleton(null));
//        if (infoList.size()>0 && infoList!=null){
//            for (C3ReportCarInfoVo c3ReportCarInfoVo : infoList) {
//                List<String> types = new ArrayList<>();
//                List<C3RiskFault> riskFaults=riskFaultService.selectTypeByVin(c3ReportCarInfoVo.getVin());
//                if (riskFaults!=null && riskFaults.size()>0){
//                    for (C3RiskFault riskFault : riskFaults) {
//                        types.add(riskFault.getType());
//                    }
//                    if (types.contains("30")){
//                        c3ReportCarInfoVo.setType("30");
//                    }else if (!types.contains("30") && types.contains("20")){
//                        c3ReportCarInfoVo.setType("20");
//                    }else {
//                        c3ReportCarInfoVo.setType("10");
//                    }
//                }
//            }
//        }
        return infoList;
    }

    @Override
    public List<C3ReportCarInfoVo> getCarCurrentLocationList(Map<String, Object> condition) {
        return getCarCurrentInfoList(condition);
//        for (C3ReportCarInfoVo c3ReportCarInfoVo : infoList) {
//            String type = riskFaultService.selectTypeByVin(c3ReportCarInfoVo.getVin());
//            if (StringUtils.isEmpty(type)){
//                c3ReportCarInfoVo.setType("10");
//            }else {
//                c3ReportCarInfoVo.setType(type);
//            }
//        }
//        if (condition.get("type")!=null && !"".equals(condition.get("type"))){
//            if ("10".equals(condition.get("type"))){
//                if (!infoList.isEmpty()) {
//                    for (C3ReportCarInfoVo info : infoList) {
//                        List<C3RiskFault> riskFaults = riskFaultService.selectTypeByVin(info.getVin());
//                        if (riskFaults.isEmpty()){
//                            info.setType("10");
//                            list.add(info);
//                        }
//                    }
//
//                }
//                return list;
//            }
//        }
//        return infoList;
    }

    @Override
    public List<C3ReportCarInfoDto> getCityCarInfoList(Map<String, Object> condition) {
        EntityWrapper<C3ReportCarInfo> ew = buildWrapper(condition);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar beforeTime = Calendar.getInstance();
        beforeTime.add(Calendar.MINUTE, -5);
        Date beforeD = beforeTime.getTime();
        condition.put("dateTime", sdf.format(beforeD));
        List<C3ReportCarInfoDto> infoDtoList = baseMapper.getCityCarInfoList(ew, condition);
        infoDtoList.removeAll(Collections.singleton(null));
//        if (infoDtoList.size()>0 && infoDtoList!=null){
//            for (C3ReportCarInfoDto c3ReportCarInfoDto : infoDtoList) {
//                List<String> types = new ArrayList<>();
//                List<C3RiskFault> riskFaults=riskFaultService.selectTypeByVin(c3ReportCarInfoDto.getVin());
//                if (riskFaults!=null && riskFaults.size()>0){
//                    for (C3RiskFault riskFault : riskFaults) {
//                        types.add(riskFault.getType());
//                    }
//                    if (types.contains("30")){
//                        c3ReportCarInfoDto.setType("30");
//                    }else if (!types.contains("30") && types.contains("20")){
//                        c3ReportCarInfoDto.setType("20");
//                    }else {
//                        c3ReportCarInfoDto.setType("10");
//                    }
//                }
//            }
//        }
        return infoDtoList;
    }

    @Override
    public Map<String, Object> getCarInfoTotal(Map<String, Object> condition) {
        EntityWrapper<C3ReportCarInfo> ew = buildWrapper2(condition);
        ew.ge("a.acquisition_time", getTodayZeroPointTimestamps());
        return baseMapper.getCarInfoTotal(ew);
    }

    private EntityWrapper<C3ReportCarInfo> buildWrapper(Map<String, Object> condition) {
        EntityWrapper<C3ReportCarInfo> ew = new EntityWrapper();
        if (condition != null) {
            if (condition.get("areaName") != null && "province".equals(condition.get("areaType"))) {
                ew.eq("c.province", condition.get("areaName").toString());
            }
            if (condition.get("areaName") != null && "city".equals(condition.get("areaType"))) {
                ew.eq("c.city", condition.get("areaName").toString());
            }
            if (condition.get("areaName") != null && "county".equals(condition.get("areaType"))) {
                ew.eq("c.county", condition.get("areaName").toString());
            }
//            if (condition.get("province") != null && !"".equals(condition.get("province"))) {
//                ew.eq("b.province", condition.get("province").toString());
//            }
//            if (condition.get("city") != null && !"".equals(condition.get("city"))) {
//                ew.eq("b.city", condition.get("city").toString());
//            }
//            if (condition.get("county") != null && !"".equals(condition.get("county"))) {
//                ew.eq("b.county", condition.get("county").toString());
//            }
            if (condition.get("vehBatSocUpper") != null && !"".equals(condition.get("vehBatSocUpper"))) {
                ew.le("b.veh_bat_soc", condition.get("vehBatSocUpper").toString());
            }
            if (condition.get("vehBatSocLower") != null && !"".equals(condition.get("vehBatSocLower"))) {
                ew.ge("b.veh_bat_soc", condition.get("vehBatSocLower").toString());
            }
            if (condition.get("startDate") != null && !"".equals(condition.get("startDate"))) {
                ew.ge("b.acquisition_time", condition.get("startDate"));
            }
            if (condition.get("endDate") != null && !"".equals(condition.get("endDate"))) {
                ew.le("b.acquisition_time", condition.get("endDate"));
            }
            if (condition.get("plateLicenseNo") != null && !"".equals(condition.get("plateLicenseNo"))) {
                ew.like("v.plate_license_no", String.valueOf(condition.get("plateLicenseNo")));
            }
            if (condition.get("fleetName") != null && !"".equals(condition.get("fleetName"))) {
                ew.like("v.fleet", String.valueOf(condition.get("fleetName")));
            }
        }
        return ew;
    }

    private EntityWrapper<C3ReportCarInfo> buildWrapper2(Map<String, Object> condition) {
        EntityWrapper<C3ReportCarInfo> ew = new EntityWrapper();
        if (condition.get("province") != null && !"".equals(condition.get("province"))) {
            ew.eq("va.province", condition.get("province").toString());
        }
        if (condition.get("city") != null && !"".equals(condition.get("city"))) {
            ew.eq("va.city", condition.get("city").toString());
        }
        if (condition.get("county") != null && !"".equals(condition.get("county"))) {
            ew.eq("va.county", condition.get("county").toString());
        }
        if (condition.get("startDate") != null && !"".equals(condition.get("startDate"))) {
            ew.ge("a.acquisition_time", condition.get("startDate"));
        }
        if (condition.get("endDate") != null && !"".equals(condition.get("endDate"))) {
            ew.le("a.acquisition_time", condition.get("endDate"));
        }
        return ew;
    }

    public static Long getTodayZeroPointTimestamps() {
        Long currentTimestamps = System.currentTimeMillis();
        Long oneDayTimestamps = Long.valueOf(60 * 60 * 24 * 1000);
        return currentTimestamps - (currentTimestamps + 60 * 60 * 8 * 1000) % oneDayTimestamps;
    }

    @Override
    public List<AreaCountDto> getAreaVehicleCount(AreaCountDto areaCountDto) {
        if (ObjectUtils.isEmpty(areaCountDto)) throw new BaseException("参数为空");
        Map<String, Object> condition = JSONObject.parseObject(JSONUtil.toJsonStr(areaCountDto), new TypeReference<Map<String, Object>>() {}, new Feature[0]);
        List<C3ReportCarInfoVo> carInfoVoList = getCarCurrentLocationList(condition);
        Map<String, List<C3ReportCarInfoVo>> groupBy = new HashMap<>(carInfoVoList.size());
        if (CollectionUtils.isNotEmpty(carInfoVoList) && "".equals(areaCountDto.getAreaType())) {
            groupBy = carInfoVoList.stream().collect(Collectors.groupingBy(C3ReportCarInfoVo::getProvince));
        }
        if (CollectionUtils.isNotEmpty(carInfoVoList) && "province".equals(areaCountDto.getAreaType())) {
            groupBy = carInfoVoList.stream().collect(Collectors.groupingBy(C3ReportCarInfoVo::getCity));
        }
        if (CollectionUtils.isNotEmpty(carInfoVoList) && "city".equals(areaCountDto.getAreaType())) {
            groupBy = carInfoVoList.stream().collect(Collectors.groupingBy(C3ReportCarInfoVo::getCounty));
        }
        if (CollectionUtils.isNotEmpty(carInfoVoList) && "county".equals(areaCountDto.getAreaType())) {
            groupBy = carInfoVoList.stream().collect(Collectors.groupingBy(C3ReportCarInfoVo::getVin));
        }
        if (groupBy.isEmpty()){
            return new ArrayList<>(1);
        }
        List<AreaCountDto> result = new ArrayList<>(groupBy.size());
        int totalSums = carInfoVoList.size(), normalSums = 0, riskSums = 0, faultSums = 0;
        for (String key : groupBy.keySet()){
            List<C3ReportCarInfoVo> data = groupBy.get(key);
            int totalSum = data.size(), normalSum = 0, riskSum = 0, faultSum = 0;
            /** 10:正常，20：风险，30：故障 */
            for (C3ReportCarInfoVo carInfoVo : data){
                if (carInfoVo.getType().equals("20")){
                    riskSum += 1;
                    continue;
                }
                if (carInfoVo.getType().equals("30")){
                    faultSum += 1;
                    continue;
                }
                normalSum += 1;
            }
            totalSums += totalSum;
            normalSums += normalSum;
            riskSums += riskSum;
            faultSums += faultSum;
            AreaCountDto areaCount = new AreaCountDto(areaCountDto.getAreaType(), key, totalSum, normalSum, riskSum, faultSum);
            result.add(areaCount);
        }
        /** 总计处理 */
        String areaName = "全国";
        if (StringUtils.isNotBlank(areaCountDto.getAreaName())){
            areaName = areaCountDto.getAreaName();
        }
        AreaCountDto areaCount = new AreaCountDto("合计", areaName, totalSums, normalSums, riskSums, faultSums);
        result.add(areaCount);
        return result;
    }




    @Override
    public List<C3ReportCarInfoDto> getCarInfoRoute(Map<String, Object> condition) {
        EntityWrapper<C3ReportCarInfo> ew = new EntityWrapper<>();
        if (condition == null || condition.isEmpty()) throw new BaseException("参数为空");
        if (condition.get("vin") != null && !"".equals(condition.get("vin"))) {
            ew.eq("r.vin", condition.get("vin").toString());
        }
        if (condition.get("plateLicenseNo") != null && !"".equals(condition.get("plateLicenseNo"))) {
            ew.eq("v.plate_license_no", condition.get("plateLicenseNo").toString());
        }
        if (condition.get("startDate") != null && !"".equals(condition.get("startDate"))) {
            ew.ge("r.acquisition_time", condition.get("startDate"));
        }
        if (condition.get("endDate") != null && !"".equals(condition.get("endDate"))) {
            ew.le("r.acquisition_time", condition.get("endDate"));
        }
        ew.ne("r.latitude", "0");
        ew.ne("r.longitude", "0");
        ew.orderBy("r.acquisition_time", Boolean.FALSE);

        return baseMapper.getCarInfoRoute(ew);
    }

    public boolean isToDay(String endDate){
        SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
        String toDay = format.format(new Date());
        if (toDay.equals(endDate)){
            return true;
        }
        return false;
    }

    @Override
    public List<MilesReportDto> getTotalFleetMiles(Map<String, Object> condition) {
        List<MilesReportDto> resultList = new ArrayList<>();

        if (condition == null || condition.isEmpty()) throw new BaseException("参数为空");

        if (condition.get("type") != null && !"".equals(condition.get("fleetListOrPlateList"))) {
            String[] fleetListOrPlateList = null;
            if ("10".equals(condition.get("type"))) {
                fleetListOrPlateList = condition.get("fleetList").toString().split(",");
            }
            if ("20".equals(condition.get("type"))) {
                fleetListOrPlateList = condition.get("plateList").toString().split(",");
            }
            for (String fleetOrPlate : fleetListOrPlateList) {
                EntityWrapper<Vehicle> ew = new EntityWrapper<>();
                if (StringUtils.isNotBlank(fleetOrPlate)){
                    ew.eq("fleet", fleetOrPlate).or().eq("plate_license_no", fleetOrPlate);
                }
                ew.eq("status", "10");
//                ew.like("fleet", fleetOrPlate).or().like("plate_license_no", fleetOrPlate).eq("status", "10");
                List<Vehicle> vehicles = vehicleService.selectList(ew);
                if (CollectionUtils.isEmpty(vehicles)) {
                    return resultList;
                }
                double totalMiles = 0;
                for (Vehicle vehicle : vehicles) {
                    EntityWrapper<C3ReportCarInfo> entityWrapper = new EntityWrapper<>();
//                    if ("".equals(condition.get("queryTime").toString()) || condition.get("queryTime") == null) {
//                        entityWrapper.where("vin={0} and TO_DAYS(gmt_create) = TO_DAYS(NOW())", vehicle.getVin());
//                    }
//                    if (condition.get("queryTime").toString().length() == 4) {
//                        entityWrapper.where("vin = {0} and DATE_FORMAT( gmt_create, '%Y' ) = {1}", vehicle.getVin(), condition.get("queryTime").toString());
//                    }
//                    if (condition.get("queryTime").toString().length() == 7) {
//                        entityWrapper.where("vin= {0} and DATE_FORMAT( gmt_create, '%Y-%m' ) = {1}", vehicle.getVin(), condition.get("queryTime").toString());
//                    }
//                    if (condition.get("queryTime").toString().length() > 7) {
//                        entityWrapper.where("vin = {0} and DATE_FORMAT( gmt_create, '%Y-%m-%d' ) = {1}", vehicle.getVin(), condition.get("queryTime").toString());
//                    }
                    entityWrapper.eq("vin",vehicle.getVin());
                    if (!"".equals(condition.get("startDate").toString()) && condition.get("startDate") != null) {
                        entityWrapper.ge("gmt_create",condition.get("startDate").toString());
                    }
                    if (!"".equals(condition.get("endDate").toString()) && condition.get("endDate") != null) {
                        if (isToDay(condition.get("endDate").toString())){
                            entityWrapper.le("gmt_create",DateUtil.format(new Date(),DateUtil.DATE_TIME));
                        }else {
                            entityWrapper.le("gmt_create",condition.get("endDate").toString());
                        }
                    }
                    double miles = c3CarCondStatisticsService.getTotalMiles(entityWrapper);
                    totalMiles += miles;
                }
                MilesReportDto milesReportDto = new MilesReportDto();
                if ("10".equals(condition.get("type"))) {
                    milesReportDto.setFleetList(fleetOrPlate);
                }
                if ("20".equals(condition.get("type"))) {
                    milesReportDto.setPlateList(fleetOrPlate);
                }
                milesReportDto.setTotalMiles(new BigDecimal(totalMiles));
                milesReportDto.setVehiclesSum(vehicles.size());
                milesReportDto.setAverageMiles(new BigDecimal(totalMiles).divide(new BigDecimal(vehicles.size()), 2, RoundingMode.HALF_UP));
                resultList.add(milesReportDto);
            }
        }
        if (condition.get("sort") != null && !"".equals(condition.get("sort"))) {
            if ("10".equals(condition.get("sort"))) {
                Collections.sort(resultList, new Comparator<MilesReportDto>() {
                    @Override
                    public int compare(MilesReportDto o1, MilesReportDto o2) {
                        int i = o1.getTotalMiles().subtract(o2.getTotalMiles()).intValue();//降序
                        return i;
                    }
                });
            }
            if ("20".equals(condition.get("sort"))) {
                Collections.sort(resultList, new Comparator<MilesReportDto>() {
                    @Override
                    public int compare(MilesReportDto o1, MilesReportDto o2) {
                        int i = o1.getVehiclesSum() - o2.getVehiclesSum();//降序
                        return i;
                    }
                });
            }
            if ("30".equals(condition.get("sort"))) {
                Collections.sort(resultList, new Comparator<MilesReportDto>() {
                    @Override
                    public int compare(MilesReportDto o1, MilesReportDto o2) {
                        int i = o1.getAverageMiles().subtract(o2.getAverageMiles()).intValue();//降序
                        return i;
                    }
                });
            }
        }
        if (!CollectionUtils.isEmpty(resultList)){
            for (MilesReportDto milesReportDto : resultList) {
                if (milesReportDto.getFleetList().length()>7){
                    String fleet=new StringBuilder(milesReportDto.getFleetList()).insert(7,"\n").toString();
                    milesReportDto.setFleetList(fleet);
                }
            }
        }
        return resultList;
    }

    @Override
    public List<Map<String, Object>> getRiskFaultRate(Map<String, Object> condition) throws ParseException {
        if (condition == null || condition.isEmpty()) throw new BaseException("参数为空");
        long start=0;
        long end=0;
        EntityWrapper<Vehicle> ew = new EntityWrapper<>();
        //if (condition.get("queryTime") != null && !"".equals(condition.get("queryTime"))) {
//            if (condition.get("queryTime").toString().length() == 4) {
//                ew.where("DATE_FORMAT( r.gmt_create, '%Y' ) = {0}", condition.get("queryTime").toString());
//            }
//            if (condition.get("queryTime").toString().length() == 7) {
//                ew.where(" DATE_FORMAT( r.gmt_create, '%Y-%m' ) = {0}", condition.get("queryTime").toString());
//            }
//            if (condition.get("queryTime").toString().length() > 7) {
//                ew.where(" DATE_FORMAT( r.gmt_create, '%Y-%m-%d' ) = {0}", condition.get("queryTime").toString());
//            }
//
//            minutes = DateUtil.getMinutesOfDateStr(condition.get("queryTime").toString());
//        }else {
//            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//            ew.where(" DATE_FORMAT( r.gmt_create, '%Y-%m-%d' ) = {0}", format.format(new Date()));
//            minutes = 1440;
            if (!"".equals(condition.get("startDate").toString()) && condition.get("startDate") != null) {
                ew.ge("r.gmt_create",condition.get("startDate").toString()+" 00:00:00");
                start =DateUtil.parse(condition.get("startDate").toString()+" 00:00:00", DateUtil.DATE_TIME).getTime();
            }
            if (!"".equals(condition.get("endDate").toString()) && condition.get("endDate") != null) {
                if (isToDay(condition.get("endDate").toString())){
                    ew.le("r.gmt_create",DateUtil.format(new Date(),DateUtil.DATE_TIME));
                    end =DateUtil.parse(DateUtil.format(new Date(),DateUtil.DATE_TIME), DateUtil.DATE_TIME).getTime();
                }else {
                    ew.le("r.gmt_create",condition.get("endDate").toString()+" 00:00:00");
                    end =DateUtil.parse(condition.get("endDate").toString()+" 00:00:00", DateUtil.DATE_TIME).getTime();
                }
            }

        long minutes = (end - start)/1000/60;
        if (minutes<=0){
            throw new BaseException("起始时间大于当前时间请重新选取时间！");
        }
        //}
        if (condition.get("fleetList") != null && !"".equals(condition.get("fleetList"))) {
            String[] fleetList = condition.get("fleetList").toString().split(",");
            ew.in("a.fleet", fleetList);

        }
        if (condition.get("plateList") != null && !"".equals(condition.get("plateList"))) {
            String[] plateList = condition.get("plateList").toString().split(",");
            ew.in("a.plate_license_no", plateList);
        }
        if (condition.get("type") != null && !"".equals(condition.get("type"))) {
            if ("10".equals(condition.get("type"))) {
                ew.groupBy("a.fleet");
            }
            if ("20".equals(condition.get("type"))) {
                ew.groupBy("a.plate_license_no");
            }
        }

        List<String> fleetList = Arrays.asList(String.valueOf(condition.get("fleetList")).split(","));
        List<Map<String, Object>> riskFaultRate = baseMapper.getRiskFaultRate(ew, condition.get("sort") == null ? "0" : condition.get("sort").toString(),minutes);
        Map<String, List<Map<String, Object>>> glist = riskFaultRate.stream().collect(Collectors.groupingBy(e -> e.get("fleet").toString()));
        List<Map<String, Object>> result = new ArrayList<>(riskFaultRate.size());
        fleetList.stream().forEach(fleet->{
            Map<String, Object> dataMap = new HashMap<>();
            if (glist.containsKey(fleet)){
                return;
            }
            if (StringUtils.isNotBlank(fleet) && fleet.length() > 7) {
                dataMap.put("fleet", new StringBuilder(fleet).insert(7, "\n").toString());
            }
            dataMap.put("fault", 0);
            dataMap.put("risk", 0);
            dataMap.put("nomalRate", 1);
            result.add(dataMap);
        });
        if (!CollectionUtils.isEmpty(riskFaultRate)) {
            riskFaultRate.stream().forEach(map -> {
                String fleet = map.get("fleet") == null ? "" : String.valueOf(map.get("fleet"));
                /*当风险 + 故障都为空，则正常率为 100%*/
                if (map.get("fault") == null && map.get("risk") == null){
                    map.put("nomalRate", "1");
                }
                if (map.get("fault") == null ){
                    map.put("fault", "0");
                }
                if (map.get("risk") == null ){
                    map.put("risk", "0");
                }
                if (StringUtils.isNotBlank(fleet) && fleet.length() > 7) {
                    map.put("fleet", new StringBuilder(fleet).insert(7, "\n").toString());
                }
                result.add(map);
            });
        }
        return result;
    }

    @Override
    public Page<Map<String, Object>> getRiskRateForVin(Page<Map<String, Object>> page) {

        if (page == null) {
            throw new BaseException("参数不能为空");
        }

        Map<String, Object> condition = page.getCondition();

        if (condition == null || condition.isEmpty()) throw new BaseException("参数为空");
        EntityWrapper<Vehicle> ew = new EntityWrapper<>();

        //int minutes = 0;
        String timeType = "";

//        if (condition.get("queryTime") != null && !"".equals(condition.get("queryTime"))) {
//            if (condition.get("queryTime").toString().length() == 4) {
//                timeType = "year";
//            }
//            if (condition.get("queryTime").toString().length() == 7) {
//                timeType = "month";
//            }
//            if (condition.get("queryTime").toString().length() > 7) {
//                timeType = "day";
//            }
//            minutes = DateUtil.getMinutesOfDateStr(condition.get("queryTime").toString());
//        }else {
//            minutes=1440;
//            timeType = "day";
//        }
            long start=0;
            long end=0;
            if (!"".equals(condition.get("startDate").toString()) && condition.get("startDate") != null) {
                //ew.ge("rf.gmt_create",condition.get("startDate").toString());
                start =DateUtil.parse(condition.get("startDate").toString()+" 00:00:00", DateUtil.DATE_TIME).getTime();
            }
            if (!"".equals(condition.get("endDate").toString()) && condition.get("endDate") != null) {
               // ew.le("rf.gmt_create",condition.get("endDate").toString());
                if (isToDay(condition.get("endDate").toString())){
                    end =DateUtil.parse(DateUtil.format(new Date(),DateUtil.DATE_TIME), DateUtil.DATE_TIME).getTime();
                    condition.put("endDate",DateUtil.format(new Date(),DateUtil.DATE_TIME));
                }else {
                    end =DateUtil.parse(condition.get("endDate").toString()+" 00:00:00", DateUtil.DATE_TIME).getTime();
                }
            }

            long minutes = (end - start)/1000/60;
            if (minutes<=0){
                throw new BaseException("起始时间大于当前时间请重新选取时间！");
            }

        if (minutes <= 0) throw new BaseException("起始时间大于当前时间请重新选取时间！");

        //if (timeType == null || "".equals(timeType)) throw new BaseException("时间格式不对，请重新选择时间");

        if (condition.get("fleetList") != null && !"".equals(condition.get("fleetList"))) {
//            String[] fleetList = condition.get("fleetList").toString().split(",");
            ew.eq("v.fleet", condition.get("fleetList"));

        }

        if (condition.get("plateList") != null && !"".equals(condition.get("plateList"))) {
            String[] plateList = condition.get("plateList").toString().split(",");
            ew.in("v.plate_license_no", plateList);
        }
        ew.groupBy("v.plate_license_no");

        List<Map<String, Object>> riskFaultRate = baseMapper.getRiskRateForVin(ew, minutes,condition.get("startDate").toString(),condition.get("endDate").toString());
        List<Map<String, Object>> result = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(riskFaultRate)){
            riskFaultRate.stream().forEach(map -> {
                String fleet = map.get("fleet") == null ? "" : String.valueOf(map.get("fleet"));
                /*当风险 + 故障都为空，则正常率为 100%*/
                if (map.get("fault") == null && map.get("risk") == null){
                    map.put("nomalRate", "1");
                }
                if (map.get("fault") == null ){
                    map.put("fault", "0");
                }
                if (map.get("risk") == null ){
                    map.put("risk", "0");
                }
                map.put("fleet", fleet);
                result.add(map);
            });
        }
        page.setRecords(result);
        return page;
    }



    /**
     * 查询车队公司统计数据
     * @author huangzhigang 2020-02-25 10:45:11
     * @param paramMap 查询条件集
     * @return List<HashMap<String, Object>>
     */
    @Override
    public List<VehiclesStatisticsPo> selVehiclesStatistics(Map<String, String> paramMap) {
        try {
            Map<String, Object> param = new HashMap<>(paramMap.size());
            param.put("startDate", paramMap.get("startDate"));
            if (isToDay(paramMap.get("endDate").toString())){
                param.put("endDate",DateUtil.format(new Date(),DateUtil.DATE_TIME));
            }else {
                param.put("endDate", paramMap.get("endDate"));
            }
            String fleetParam = paramMap.get("fleetList");
            List<String> fleetList = new ArrayList<>();
            fleetList = Arrays.asList(fleetParam.split(","));
            if (StringUtils.isNotBlank(fleetParam)){
                fleetList = Arrays.asList(fleetParam.split(","));
            }
            param.put("fleetList", fleetList);
            List<VehiclesStatisticsPo> fleets = baseMapper.selCarCondStatisticsData(param);
            List<VehiclesStatisticsPo> fleetUnusualCnts = baseMapper.selCarCondStatisticsData1(param);
            Map<Long, List<VehiclesStatisticsPo>> fleetUnusualCntsGroupBy = fleetUnusualCnts.stream().collect(Collectors.groupingBy(VehiclesStatisticsPo::getFleetId));
            if (CollectionUtils.isEmpty(fleetUnusualCnts)){
                return new ArrayList<>();
            }
            List<VehiclesStatisticsPo> datalist = new ArrayList<>();
            fleets.stream().forEach(fleet->{
                Long fleetId = fleet.getFleetId();
                List<VehiclesStatisticsPo> leetUnusualCntList = fleetUnusualCntsGroupBy.get(fleetId);
                List<String> unusualTypes = Arrays.asList(new String[]{"1","2","3","4"});
                VehiclesStatisticsPo vehiclesStatistics = dataDb(leetUnusualCntList, unusualTypes);
                vehiclesStatistics.setTotalDistance(fleet.getTotalDistance());
                vehiclesStatistics.setFleetId(fleetId);
                vehiclesStatistics.setFleetName(fleet.getFleetName());
                datalist.add(vehiclesStatistics);
            });
            Collections.sort(datalist, Comparator.comparing(VehiclesStatisticsPo::getTotalDistance).reversed());
            return datalist;
        }catch (Exception e){
            LOGGER.info(e.getMessage(), e);
        }
        return new ArrayList<>();
    }

    /**
     * 车队公司及车辆汇总数据
     * @param vin 车架号
     * @return List<VehiclesStatisticsPo>
     */
    @Override
    public VehiclesStatisticsPo selVehiclesStatisticsList(String vin) {
        try {
            if (StringUtils.isBlank(vin)){
                return null;
            }
            Map<String, String> param = new HashMap<>(1);
            param.put("vin", vin);
            return baseMapper.selVehiclesStatisticsList(param);
            // SELECT r.vin, r.count, r.start_time, r.end_time, r.type FROM lisa_vehicle.c3_risk_fault r WHERE r.vin = ''
        }catch (Exception e){
            LOGGER.info(e.getMessage(), e);
        }
        return null;
    }

    @Override
    public boolean reportCarHandle(List<C3ReportCarInfo> dataList) {
        try {
            dataList.stream().forEach(c3ReportCarInfo->{
                if (c3ReportCarInfo.getLongitude().compareTo(BigDecimal.ZERO)==0 || c3ReportCarInfo.getLatitude().compareTo(BigDecimal.ZERO)==0){
                    return;
                }
                Map<String, String> transAddress = DriveDirectionUtil.transAddress(c3ReportCarInfo);
                if (transAddress.isEmpty()){
                    return;
                }
                if (transAddress.containsKey("province") && StringUtils.isNotBlank(transAddress.get("province"))){
                    c3ReportCarInfo.setProvince(transAddress.get("province"));
                }
                if (transAddress.containsKey("city") && StringUtils.isNotBlank(transAddress.get("city"))){
                    c3ReportCarInfo.setCity(transAddress.get("city"));
                }
                if (transAddress.containsKey("district") && StringUtils.isNotBlank(transAddress.get("district"))){
                    c3ReportCarInfo.setCounty(transAddress.get("district"));
                }
                if (transAddress.containsKey("detailedAddr") && StringUtils.isNotBlank(transAddress.get("detailedAddr"))){
                    c3ReportCarInfo.setDetailedAddr(transAddress.get("detailedAddr"));
                }
                C3ReportCar1Info c3ReportCar1Info = new C3ReportCar1Info();
                BeanUtils.copyProperties(c3ReportCarInfo, c3ReportCar1Info);
                baseMapper.insert(c3ReportCarInfo);
                c3ReportCarInfo1Service.add(c3ReportCar1Info);
            });
            return true;
        }catch (Exception e){
            LOGGER.info(e.getMessage(), e);
        }
        return false;
    }

    private VehiclesStatisticsPo dataDb(List<VehiclesStatisticsPo> fleetUnusualCntList, List<String> unusualTypes){
        VehiclesStatisticsPo vehiclesStatistics = new VehiclesStatisticsPo();
        if (CollectionUtils.isEmpty(fleetUnusualCntList)){
            vehiclesStatistics.setTotalDistance(0.0d);
            vehiclesStatistics.setFault(0);
            vehiclesStatistics.setFaultCnt(0);
            vehiclesStatistics.setRisk(0);
            vehiclesStatistics.setRiskCnt(0);
            vehiclesStatistics.setDrivingBehavior(0);
            vehiclesStatistics.setDrivingBehaviorCnt(0);
            vehiclesStatistics.setFatigueDriving(0);
            vehiclesStatistics.setFatigueDrivingCnt(0);
            return vehiclesStatistics;
        }
        Map<Integer, List<VehiclesStatisticsPo>> fleetUnusualCntListGroupBy = fleetUnusualCntList.stream().collect(Collectors.groupingBy(VehiclesStatisticsPo::getUnusualType));
        unusualTypes.stream().forEach(type->{
            int vehiclesCnt = 0;
            List<VehiclesStatisticsPo> unusualList = fleetUnusualCntListGroupBy.get(Integer.parseInt(type));
            if (!CollectionUtils.isEmpty(unusualList)){
                vehiclesCnt = unusualList.get(0).getVehiclesCnt();
            }
            if ("2".equals(type)){
                vehiclesStatistics.setRiskCnt(vehiclesCnt);
            }
            if ("3".equals(type)){
                vehiclesStatistics.setFaultCnt(vehiclesCnt);
            }
            if ("4".equals(type)){
                vehiclesStatistics.setDrivingBehaviorCnt(vehiclesCnt);
            }
        });
        return vehiclesStatistics;
    }

}
